package first.group.ssh.gui.model;

import first.group.ssh.gui.dialog.AboutDialog;
import first.group.ssh.gui.dialog.ConnectDialog;
import first.group.ssh.gui.frame.MainFrame;
import first.group.ssh.gui.state.MainState;
import first.group.ssh.gui.util.TabUtil;
import javax.swing.DefaultSingleSelectionModel;
import javax.swing.SingleSelectionModel;

public class MainModel {
    private MainFrame frame = null;
    private final MainState state = MainState.getInstance();
    private final SingleSelectionModel tabSelectionModel = new DefaultSingleSelectionModel();
    
    private boolean stateListening = false;
    private final MainState.Listener listener = new MainState.Listener() {
        @Override
        public void onRecordAdded(MainState.SessionRecord record) {
            refresh();
        }

        @Override
        public void onRecordRemoved(MainState.SessionRecord record) {
            refresh();
        }
    };
    
    public void bindToFrame(MainFrame frame) {
        if (this.frame != null) {
            throw new IllegalStateException("This model is already bound to a frame");
        }
        this.frame = frame;
        frame.connectionsPane.setModel(tabSelectionModel);
        refresh();
        if (!stateListening) {
            stateListening = true;
            state.addListener(listener);
        }
    }
    
    private void refresh() {
        updateSessions();
        switchSession(state.getActiveRecord());
    }
    
    private void switchSession(MainState.SessionRecord session) {
        if (session == null) {
            frame.disconnectItem.setEnabled(false);
            frame.centerPanel.setVisible(true);
        } else {
            frame.disconnectItem.setEnabled(true);
            frame.centerPanel.setVisible(false);
        }
    }
    
    private void updateSessions() {
        frame.connectionsPane.removeAll();
        for (var record : state.getRecords()) {
            TabUtil.addTab(frame.connectionsPane, record.session().address.getHostString(), record.widget(), () -> {
                state.closeRecord(record);
            });
            var index = frame.connectionsPane.getTabCount();
            if (state.getActiveRecord() == record) {
                frame.connectionsPane.setSelectedIndex(index - 1);
            }
        }
    }
    
    public void openAboutDialog() {
        new AboutDialog(frame, true).setVisible(true);
    }
    
    public void openConnectDialog() {
        new ConnectDialog(frame, true).setVisible(true);
    }

    public void disconnect() {
        var record = state.getActiveRecord();
        if (record == null) {
            return;
        }
        record.session().disconnect();
    }
    
    public void exit() {
        frame.dispose();
    }
    
    public void dispose() {
        stateListening = false;
        state.removeListener(listener);
    }
}
